package com.hotel.BL;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.EntityName;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import data.Package;
import data.PackageByDate;
import data.PackagePrice;
import data.Reservation;

public class PackageLogic extends AbstractBL {
	public PackageLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}
	public List<Package> GeneratePackage(long hotelId)
	{
		PackagePriceLogic packagePriceLogic = new PackagePriceLogic(req,resp);
		RoomTypeLogic roomtypeLogic = new RoomTypeLogic(req,resp);
		
		long iSuite = roomtypeLogic.GetRoomType(hotelId,"iSuite").getId();
		long iDeluxeKingbed = roomtypeLogic.GetRoomType(hotelId,"iDeluxe King Bed").getId();
		long iDeluxeQueenbed =roomtypeLogic.GetRoomType(hotelId,"iDeluxe Queen Bed").getId(); 
		
		List<PackagePrice> list1 = new ArrayList<PackagePrice>();
		list1.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iSuite),700,300,50));
		list1.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iDeluxeKingbed),400,300,50));
		list1.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iDeluxeQueenbed),400,300,50));

		List<PackagePrice> list2 = new ArrayList<PackagePrice>();
		list2.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iSuite),700,300,50));
		list2.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iDeluxeKingbed),400,300,50));

		List<PackagePrice> list3 = new ArrayList<PackagePrice>();
		list3.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iSuite),1500,800,100));
		list3.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iDeluxeKingbed),1300,200,100));
		list3.add(packagePriceLogic.GetPackagePrice(hotelId,String.valueOf(iDeluxeQueenbed),1000,500,100));

		Package pk;
		List<Package> list = new ArrayList<Package>();
		
		if(GetPackage(hotelId,"Complimentary")==null){
			pk = new Package();
			pk.setHotelId(hotelId);
			pk.setName("Complimentary");
			pk.setShortName("package1");
			pk.setLengthOfStay(1);
			pk.setDescription("");
			pk.setPackagepriceList(list1);
			pk.setStatus(true);
			pk.setAvaliable(true);
			list.add(pk);
		}
		if(GetPackage(hotelId,"Gift Voucher")==null){
			pk = new Package();
			pk.setHotelId(hotelId);
			pk.setName("Gift Voucher");
			pk.setShortName("package2");
			pk.setLengthOfStay(1);
			pk.setDescription("");
			pk.setPackagepriceList(list2);
			pk.setStatus(true);
			pk.setAvaliable(true);
			list.add(pk);
		}
		if(GetPackage(hotelId,"Agoda Rate")==null){
			pk = new Package();
			pk.setHotelId(hotelId);
			pk.setName("Agoda Rate");
			pk.setShortName("package3");
			pk.setLengthOfStay(1);
			pk.setDescription("");
			pk.setPackagepriceList(list1);
			pk.setStatus(true);
			pk.setAvaliable(true);
			list.add(pk);
		}
		if(GetPackage(hotelId,"Default")==null){
			pk = new Package();
			pk.setHotelId(hotelId);
			pk.setName("Default");
			pk.setShortName("package4");
			pk.setLengthOfStay(1);
			pk.setDescription("");
			pk.setPackagepriceList(list3);
			pk.setStatus(true);
			pk.setAvaliable(true);
			list.add(pk);
		}
		
		return list;
	}
	
	public Package GetPackage(long id)
	{
		Key key = KeyFactory.createKey(EntityName.Package, id);
		try {
			Entity lang = datastore.get(key);
			Package c = new Package();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
		
	public List<Package> GetAllPackage(long hotelId)
	{
		Query q = new Query(EntityName.Package);
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		q.setFilter(filterHotel);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
	
	public Package GetPackage(Entity entity)
	{
		if(entity == null) return null;
		Package item = new Package();
		item.setEntity(entity);
		return item;
	}
	
	public List<Package> GetList(List<Entity> entities)
	{
		List<Package> list = new ArrayList<Package>();
		for(Entity e : entities)
		{
			Package a = new Package();
			a.setEntity(e);
			list.add(a);
		}
		return list;
	}

	public Package AddPackage(long hotelId,String Name,String shortName,long lengthOfStay,String Description,String packagepriceListString) throws EntityNotFoundException{
		Package t = new Package();
		t.setHotelId(hotelId);
		t.setName(Name);
		t.setShortName(shortName);
		t.setLengthOfStay(lengthOfStay);
		t.setDescription(Description);
		t.setPackagepriceListString(packagepriceListString);
		t.setAvaliable(true);
		t.setStatus(true);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public Package EditPackage(long packageId,String Name,String shortName,long lengthOfStay,String Description,String packagepriceListString) throws EntityNotFoundException{
		Package t = GetPackage(packageId);
		t.setName(Name);
		t.setShortName(shortName);
		t.setLengthOfStay(lengthOfStay);
		t.setDescription(Description);
		t.setPackagepriceListString(packagepriceListString);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public Package DeletePackage(long packageId) throws EntityNotFoundException{
		Package t = GetPackage(packageId);
		t.setAvaliable(false);
		t.setStatus(false);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public void DeletePackageByDate(long packageId){
		PackageByDate t = GetPackageByDate(packageId);
		//Key k = datastore.put(t.getEntity());
		//datastore.delete(k);
		datastore.delete(t.getEntity().getKey());
	}
	
	public Package ChangeStatus(long packageId) throws EntityNotFoundException{
		
		Package a = GetPackage(packageId);
		if(a.isStatus() == true){
			a.setStatus(false);
		}else if(a.isStatus() == false){
			a.setStatus(true);
		}
		 
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public Package GetPackage(long hotelId,String title)
	{
		Query q = new Query(EntityName.Package);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterTitle = new FilterPredicate("Name",FilterOperator.EQUAL,title);

		Filter filter = CompositeFilterOperator.and(filterHotel,filterTitle);
		
		q.setFilter(filter);
		
		return GetPackage(datastore.prepare(q).asSingleEntity());
	}
	
	public PackageByDate GetPackageByDate(long id)
	{
		Key key = KeyFactory.createKey(EntityName.PackageByDate, id);
		try {
			Entity lang = datastore.get(key);
			PackageByDate c = new PackageByDate();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
		
	}
	
	public Package GetPackageByDate(List<PackageByDate> packageByDate,Date date){
		for(int i = 0; i< packageByDate.size();i++){
			if(!(date.before(packageByDate.get(i).getDateFrom()) || date.after(packageByDate.get(i).getDateTo()) || date.equals(packageByDate.get(i).getDateTo())))
				return packageByDate.get(i).getPackages();
		}
		return null;
	}
	
	public PackageByDate AddPackageByDate(String packageString,Date DF,Date DT) throws EntityNotFoundException{
		PackageByDate t = new PackageByDate();
		t.setDateFrom(DF);
		t.setDateTo(DT);
		t.setPackageString(packageString);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public PackageByDate EditPackageByDate(long packageId,Date DF,Date DT,String packageString) throws EntityNotFoundException{
		PackageByDate t = GetPackageByDate(packageId);
		t.setDateFrom(DF);
		t.setDateTo(DT);
		t.setPackageString(packageString);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public PackageByDate EditPackageByDate(long packageId,String packageString) throws EntityNotFoundException{
		PackageByDate t = GetPackageByDate(packageId);
		t.setPackageString(packageString);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public void AddtoReservation(long resId,String pacId)throws EntityNotFoundException{
		Reservation r = new ReservationLogic(req,resp).GetReservation(resId);

		if(r.getPackageByDateString()!= null)
		{
			r.setPackageByDateString(r.getPackageByDateString()+","+pacId);
			
		}
		Key k = datastore.put(r.getEntity());
		r.setId(k.getId());
		r.setKey(k);
	}

}

